//
//  MMA_TrackingInfoService.m
//  MobileTracking
//
//  Created by Wenqi on 14-3-14.
//  Copyright (c) 2014年 Admaster. All rights reserved.
//

#import "MMA_TrackingInfoService.h"
#import "MMA_SSNetworkInfo.h"
#import "MMA_LocationService.h"
#import <AdSupport/AdSupport.h>
#if __has_include(<AppTrackingTransparency/AppTrackingTransparency.h>)
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#endif


#import "MMA_Reachability.h"
#import "MMA_Macro.h"
#import <SystemConfiguration/CaptiveNetwork.h>
 

@interface MMA_TrackingInfoService ()
@property (nonatomic, strong) NSMutableDictionary * oldDateDic;
@property (nonatomic) MMA_Reachability *internetReachability;
@end

@implementation MMA_TrackingInfoService{
    
    NSString * _macAddress;
    NSString * _ipAddress;
    NSString * _systemVerstion;
    NSString * _idfa;
    NSString * _scwh;
    NSString * _appKey;
    NSString * _appName;
    NSString * _location;
    NSString * _term;
    NSString * _idfv;
    NSInteger  _networkCondition;
    NSString * _wifiSSID;
    NSString * _wifiBSSID;
    NSString * _att;
    
    
    
    
}

+ (MMA_TrackingInfoService *)sharedInstance {
    static MMA_TrackingInfoService *_sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedInstance = [[self alloc] init];
        
        _sharedInstance.oldDateDic = [[NSMutableDictionary alloc]init];
        [[NSNotificationCenter defaultCenter] addObserver:_sharedInstance selector:@selector(reachability) name:MMA_ReachabilityChangedNotification object:nil];
        
        [_sharedInstance reachability];
 
        _sharedInstance.internetReachability = [MMA_Reachability reachabilityForInternetConnection];
            [_sharedInstance.internetReachability startNotifier];
        
        
     
        
    });
    return _sharedInstance;
}


- (NSString *)macAddress
{
    if (_macAddress&&![self intervalTime:@"_macAddress"]) {
        return  _macAddress;
    }
    NSString *macAddress = [MMA_SSNetworkInfo currentMACAddress];
    _macAddress = macAddress ? macAddress : @"";
    [self.oldDateDic addEntriesFromDictionary:@{@"_macAddress":[NSDate date]}];
    return _macAddress;
}

- (NSString *)ipAddress
{
//    if (_ipAddress&&![self intervalTime:@"_ipAddress"]) {
//        return  _ipAddress;
//    }
    _ipAddress =  [MMA_SSNetworkInfo currentIPAddress];
//    [self.oldDateDic addEntriesFromDictionary:@{@"_ipAddress":[NSDate date]}];
    return _ipAddress;
}

- (NSString *)systemVerstion
{
    if (_systemVerstion&&![self intervalTime:@"_systemVerstion"]) {
        return  _systemVerstion;
    }
    
    _systemVerstion = [[UIDevice currentDevice] systemVersion];
    [self.oldDateDic addEntriesFromDictionary:@{@"_systemVerstion":[NSDate date]}];
    return _systemVerstion;
}

- (NSString *)idfa
{
    if (_idfa&&![self intervalTime:@"_idfa"]) {
        return  _idfa;
    }
    
    NSString *idfa = nil;
    
    
    
    if (@available(iOS 14, *)) {
#if __has_include(<AppTrackingTransparency/AppTrackingTransparency.h>)
        if ([ATTrackingManager trackingAuthorizationStatus] == ATTrackingManagerAuthorizationStatusAuthorized||[ATTrackingManager trackingAuthorizationStatus]==ATTrackingManagerAuthorizationStatusNotDetermined) {
            idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        }
#endif
    } else {
        
        if ([[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]) {
            idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
        }
    }
    
    _idfa =idfa&&![idfa isEqualToString:@"00000000-0000-0000-0000-000000000000"] ? idfa : @"";
    [self.oldDateDic addEntriesFromDictionary:@{@"_idfa":[NSDate date]}];
    return _idfa;
}

- (NSString *)scwh
{
    if (_scwh&&![self intervalTime:@"_scwh"]) {
        return  _scwh;
    }
    
    CGRect rect = [[UIScreen mainScreen] bounds];
    CGFloat scale = [[UIScreen mainScreen] scale];
    
    _scwh = [NSString stringWithFormat:@"%.2fx%.2f", rect.size.width * scale, rect.size.height * scale];
    [self.oldDateDic addEntriesFromDictionary:@{@"_scwh":[NSDate date]}];
    return _scwh;
}

- (NSString *)appKey
{
    if (_appKey&&![self intervalTime:@"_appKey"]) {
        return  _appKey;
    }
    _appKey = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleIdentifierKey];
    [self.oldDateDic addEntriesFromDictionary:@{@"_appKey":[NSDate date]}];
    return _appKey;
}
- (NSString *)appName
{
    if (_appName&&![self intervalTime:@"_appName"]) {
        return  _appName;
    }
    _appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(NSString*)kCFBundleNameKey];
    [self.oldDateDic addEntriesFromDictionary:@{@"_appName":[NSDate date]}];
    return _appName;
}



- (NSString *)location
{
    if (_location&&![self intervalTime:@"_location"]) {
        return  _location;
    }
    
    CLLocation *currentLocation = [[MMA_LocationService sharedInstance] getCurrentLocation];
    if(currentLocation==nil) {
        
        return @"";
    }
    double latitude = [((CLLocation *) currentLocation) coordinate].latitude;
    double longitude = [((CLLocation *) currentLocation) coordinate].longitude;
    double horizontalAccuracy =  ((CLLocation *) currentLocation).horizontalAccuracy;
    _location = [NSString stringWithFormat:@"%fx%fx%f", latitude, longitude, horizontalAccuracy];
    [self.oldDateDic addEntriesFromDictionary:@{@"_location":[NSDate date]}];
    return _location;
    
    
    
}

- (NSString *)term
{
    if (_term&&![self intervalTime:@"_term"]) {
        return  _term;
    }
    
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *machine = alloca(size);
    sysctlbyname("hw.machine", machine, &size, NULL, 0);
    NSString * platform = [NSString stringWithUTF8String:machine];
    
    _term = platform?platform:@"";
    [self.oldDateDic addEntriesFromDictionary:@{@"_term":[NSDate date]}];
    return _term;
}

- (NSString *)idfv
{
    if (_idfv&&![self intervalTime:@"_idfv"]) {
        return  _idfv;
    }
    
    if ([UIDevice.currentDevice respondsToSelector:@selector(identifierForVendor)]) {
        _idfv = [UIDevice.currentDevice.identifierForVendor UUIDString];
    }else{
        _idfv = @"";
    }
    [self.oldDateDic addEntriesFromDictionary:@{@"_idfv":[NSDate date]}];
    return _idfv;
}

- (NSInteger)networkCondition
{
//    if (_networkCondition&&![self intervalTime:@"_networkCondition"]) {
//        return  _networkCondition;
//    }
    
    //    NetworkStatus status = [[MMA_Reachability reachabilityForLocalWiFi] currentReachabilityStatus];
//    NetworkStatus status = [[MMA_Reachability reachabilityForInternetConnection] currentReachabilityStatus];
//
//    switch (status) {
//        case NotReachable:
//            _networkCondition= NETWORK_STATUS_NO;
//            break;
//        case ReachableViaWiFi:
//            _networkCondition= NETWORK_STATUS_WIFI;
//            break;
//        case ReachableViaWWAN:
//            _networkCondition = NETWORK_STATUS_3G;
//            break;
//    }
//    [self.oldDateDic addEntriesFromDictionary:@{@"_networkCondition":[NSDate date]}];
    return  _networkCondition;
}

- (NSString *)wifiSSID {
    if (_wifiSSID&&![self intervalTime:@"_wifiSSID"]) {
        return  _wifiSSID;
    }
    
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    id info = nil;
    for ( NSString *ifname in ifs ) {
        info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifname);
        if ( info && [info count] ) break;
    }
    NSString *ssid = [(NSDictionary *)info objectForKey:@"SSID"];
    if(ssid==nil) {
        return @"";
    }
    _wifiSSID = ssid;
    [self.oldDateDic addEntriesFromDictionary:@{@"_wifiSSID":[NSDate date]}];
    return _wifiSSID;
}
- (NSString *)wifiBSSID {
    if (_wifiBSSID&&![self intervalTime:@"_wifiBSSID"]) {
        return  _wifiBSSID;
    }
    NSArray *ifs = (__bridge_transfer id)CNCopySupportedInterfaces();
    id info = nil;
    for ( NSString *ifname in ifs ) {
        info = (__bridge_transfer id)CNCopyCurrentNetworkInfo((__bridge CFStringRef)ifname);
        if ( info && [info count] ) break;
    }
    NSString *bssid = [(NSDictionary *)info objectForKey:@"BSSID"];
    if(bssid==nil) {
        return @"";
    }
    bssid = bssid.length < 17 ? [self standardFormateMAC:bssid] : bssid;
    
    _wifiBSSID  = [[bssid stringByReplacingOccurrencesOfString:@":" withString:@""] uppercaseString];
    [self.oldDateDic addEntriesFromDictionary:@{@"_wifiBSSID":[NSDate date]}];
    return _wifiBSSID;
    
}
- (NSString *)att
{
    @try {
        if (_att&&![self intervalTime:@"_att"]) {
            return  _att;
        }
        
        
        NSString *att = nil;
        
        
        
        if (@available(iOS 14, *)) {
#if __has_include(<AppTrackingTransparency/AppTrackingTransparency.h>)
            
            att = [NSString stringWithFormat:@"%lu",(unsigned long)[ATTrackingManager trackingAuthorizationStatus]];
            
#endif
        } else {
            
            att = @"";
        }
        
        _att =att ? att : @"";
        [self.oldDateDic addEntriesFromDictionary:@{@"_att":[NSDate date]}];
        return _att;
        
    } @catch (NSException *exception) {
        
    }
}

- (NSString *)standardFormateMAC:(NSString *)MAC {
    @try {
        NSArray * subStr = [MAC componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@":-"]];
        NSMutableArray * subStr_M = [[NSMutableArray alloc] initWithCapacity:0];
        for (NSString * str in subStr) {
            if (1 == str.length) {
                NSString * tmpStr = [NSString stringWithFormat:@"0%@", str];
                [subStr_M addObject:tmpStr];
            } else {
                [subStr_M addObject:str];
            }
        }
        
        NSString * formateMAC = [subStr_M componentsJoinedByString:@":"];
        
        return [formateMAC lowercaseString];
        
    } @catch (NSException *exception) {
        NSLog(@"%@",exception);
        return @"00:00:00:00:00:00";
    }
}

/*
 * 暂时使用秒作为计算单位
 *
 */
+ (long long)timestamp {
    return [[NSDate date] timeIntervalSince1970];
}


-(BOOL)intervalTime:(NSString *)oldDateKey{
    @try {
        
        NSDate * oldDate = self.oldDateDic[oldDateKey];
        if (!oldDate) {
            return  NO;
        }
        NSDate *currentDate = [NSDate date];
        
        NSInteger secDifference = [currentDate timeIntervalSince1970] - [oldDate  timeIntervalSince1970];
        
        if (labs(secDifference)>SENSOR_UPDATE_INTERVAL) {
            [self.oldDateDic addEntriesFromDictionary:@{oldDateKey:currentDate}];
            return  YES;
        }else{
            return NO;
        }
    } @catch (NSException *exception) {
        return NO;
    }

}
- (void)reachability{
//    NotReachable = 0,
//    ReachableViaWiFi = 2,
//    ReachableViaWWAN = 1
    NetworkStatus status = [MMA_Reachability reachabilityForInternetConnection].currentReachabilityStatus;
    
     
    
    switch (status) {
        case NotReachable:
            _networkCondition= NETWORK_STATUS_NO;
            break;
        case ReachableViaWiFi:
            _networkCondition= NETWORK_STATUS_WIFI;
            break;
        case ReachableViaWWAN:
            _networkCondition = NETWORK_STATUS_3G;
            break;
    }
 
    
}

@end
